from enum import StrEnum
from typing import Optional

from pydantic import BaseModel, Field

from app.models.enums import StatusType


class MenuType(StrEnum):
    CATALOG = "catalog"  # 目录
    MENU = "menu"  # 菜单
    BUTTON = "button"  # 按钮


class BaseMenu(BaseModel):
    """菜单"""
    id: int
    name: str
    path: str
    remark: Optional[dict]
    menu_type: Optional[MenuType]
    icon: Optional[str]
    order: int
    parent_id: int
    is_hidden: bool
    component: str
    keepalive: bool
    redirect: Optional[str]
    children: Optional[list["BaseMenu"]]


class MenuCreate(BaseModel):
    """创建"""
    code: str = Field(..., description="编码")
    menu_type: MenuType = Field(default=MenuType.CATALOG.value)
    name: str = Field(examples=["用户管理"])
    icon: Optional[str] = Field(None, description="图标")
    title: Optional[str] = Field(None, description="国际化标题编码")
    status: Optional[int] = Field(StatusType.ENABLED, description="状态")

    path: str = Field(examples=["/system/user"])
    order: Optional[int] = Field(examples=[1])
    parent_id: Optional[int] = Field(examples=[0], default=0)
    is_hidden: Optional[bool] = False
    component: str = Field(None, examples=["/system/user"])
    keepalive: Optional[bool] = True
    redirect: Optional[str] = ""


class MenuUpdate(BaseModel):
    """修改"""
    id: int
    menu_type: Optional[MenuType] = Field(examples=[MenuType.CATALOG.value])
    name: Optional[str] = Field(examples=["用户管理"])
    icon: Optional[str] = Field(None, description="图标")
    title: Optional[str] = Field(None, description="国际化标题编码")
    status: Optional[int] = Field(None, description="状态")
    path: Optional[str] = Field(examples=["/system/user"])
    order: Optional[int] = Field(examples=[1])
    parent_id: Optional[int] = Field(examples=[0])
    is_hidden: Optional[bool] = False
    component: str = Field(None, description="组件", examples=["/system/user"])
    keepalive: Optional[bool] = False
    redirect: Optional[str] = ""

class VbenMenuMeta(BaseModel):
    """vben-admin的菜单元数据格式"""
    icon: Optional[str] = Field(None, description="图标")
    order: Optional[int] = Field(..., description="排序")
    title: Optional[str] = Field(None, description="标题")
    keepAlive: Optional[bool] = Field(None, description="开启KeepAlive缓存")

class VbenMenu(BaseModel):
    """vben-admin的菜单格式"""
    id: int = Field(..., description="编号")
    parentId: int = Field(..., description="父编号")
    menuType: Optional[MenuType] = Field(..., description="菜单类型")
    code: Optional[str] = Field(..., description="菜单编码")
    name: Optional[str] = Field(..., description="菜单名称")
    path: Optional[str] = Field(None, description="菜单路径")
    component: Optional[str] = Field(None, description="组件")
    redirect: Optional[str] = Field(None, description="重定向")

    meta: Optional[VbenMenuMeta] = Field(None, description="元数据")
    children: Optional[list["VbenMenu"]]

    @classmethod
    def menu_to_vben(cls, menu):
        """把menu转换为VbenMenu"""
        meta = VbenMenuMeta(icon=menu.icon, order=menu.order, keepAlive=menu.keepalive,
                            title=menu.title if menu.title else menu.name, )
        return VbenMenu(
            id=menu.id,
            parentId=menu.parent_id,
            menuType=menu.menu_type,
            code=menu.code,
            name=menu.name,
            path=menu.path,
            component=menu.component,
            redirect=menu.redirect,
            meta=meta,
            children=[]
        )
